<?php

namespace App\Jobs;

use App\Constant\ThirdMoneyCode;
use App\Events\RepayMentEvent;
use App\Exceptions\GeneralException;
use App\Facades\MoneyPlatformRequestFacade;
use App\Library\String\Strings;
use App\Library\Traits\RepaySmsRemind;
use App\Models\RepayRecord;
use App\Models\RepaySummary;
use App\Models\UserGlobal;
use Carbon\Carbon;
use Exception;
use App\Constant\QueueKey;
use App\Models\RepayRecordMoney;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Events\CollectionReceiptEvent;

class RepayMoneyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, RepaySmsRemind;

    /**
     * 任务最大尝试次数。
     *
     * @var int
     */
    public $tries = 5;

    /**
     * 任务运行的超时时间。
     *
     * @var int
     */
    public $timeout = 300; //秒数

    /**
     * @var
     */
    public $record_money_id; //资方接口记录表id

    /**
     * RepayMoneyJob constructor.
     * @param $record_money_id
     */
    public function __construct($record_money_id)
    {
        $this->onQueue(QueueKey::QUEUE_REPAY_MONEY_RESULT);
        $this->record_money_id = $record_money_id;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $model = RepayRecordMoney::find($this->record_money_id);
        if (RepayRecordMoney::STATUS_TWO == $model->status) {
            $result = MoneyPlatformRequestFacade::getMoneyRepayResult([
                'third_repay_id' => $model['third_repay_id'],
                'trade_no' => $model['trade_no'],
            ]);
            $data = $result['data'];
            if (ThirdMoneyCode::RESULT_STATUS_SUCCESS == $data['resultStatus']) {
                $this->_success($model, $data);
                Log::debug('repay_get_money_result', ['message' => '处理成功']);
            } else if (ThirdMoneyCode::RESULT_STATUS_FAILURE == $data['resultStatus']) {
                //失败
                $this->_failure($model, $data);
                Log::debug('repay_get_money_result', ['message' => '处理失败']);
            } else if (ThirdMoneyCode::RESULT_STATUS_PROCESSING == $data['resultStatus']) {
            } else {
                //未捕获结果
                Log::debug('repay_get_money_result', ['message' => '未捕获结果', 'data' => $data]);
            }
            $this->delete();
        }
        return ;
    }

    /**
     * Description: 资金成功处理
     * Author: Gxs
     * @param $model
     * @param array $data
     * @return bool
     * @throws GeneralException
     */
    private function _success($model, $data = [])
    {
        $repay_plan_data = [];
        try {
            DB::beginTransaction();
            $summary_model = RepaySummary::where('id', $model->summary_id)->first();
            if (0 == $model->period) {
                //全部还清
                //本队列对应的资方表
                $repay_plan_data = RepaySummary::mapMoneyDataFromThirdApi($summary_model->loan_id); //全部还款计划表
                Log::debug('repay_get_money_result', ['data' => $repay_plan_data, 'summary_id' => $model->summary_id]);
                if ($repay_plan_data) {
                    $end_data = end($repay_plan_data);
                } else {
                    $end_data = [];
                }
                $where = [
                    ['summary_id', '=', $model->summary_id],
                    ['status', '<>', $model::STATUS_FOUR],
                ];
                //资方表
                if (false == strtotime($data['resultRepayDate'])) {
                    $repay_date = Carbon::now();
                } else {
                    $repay_date =  Carbon::createFromTimeString($data['resultRepayDate'])->toDateString();
                }
                $model::where($where)->update([
                    'pay_order_no' => isset($data['payOrderNo']) ? $data['payOrderNo'] : '', //更新资方京东商户订单号
                    'manage_money' => 0,//提前结清的贷后管理费0
                    'status' => RepayRecordMoney::STATUS_FOUR,
                    'status_time' => Carbon::now(),
                    'type' => empty($end_data) ? 0 : RepayRecordMoney::$third_map_type[$end_data['status']],
                    'repay_date' => $repay_date,
                ]);
            } else {
                //单期
                $repay_plan_data = RepaySummary::mapMoneyDataFromThirdApi($summary_model->loan_id,$model->period);
                if (false == $repay_plan_data)
                    Log::debug('repay_get_money_result', ['message' => '三方还款计划接口异常,请查看日志']);
                if (isset(RepayRecordMoney::$third_map_type[$repay_plan_data['status']])) {
                    $success_type = RepayRecordMoney::$third_map_type[$repay_plan_data['status']];
                } else {
                    $success_type = 0;
                    Log::debug('repay_get_money_result', ['message' => $model->period . '期三方还款计划接口状态码错误', 'data' => $repay_plan_data]);
                }

                //资金接口表
                if (!isset($data['resultRepayDate']) || false == strtotime($data['resultRepayDate'])) {
                    $repay_date = Carbon::now();
                } else {
                    $repay_date = Carbon::createFromTimeString($data['resultRepayDate'])->toDateString();
                }
                $model->update([
                    'pay_order_no' => isset($data['payOrderNo']) ? $data['payOrderNo'] : '', //更新资方京东商户订单号
                    'status' => RepayRecord::STATUS_FOUR,
                    'status_time' => Carbon::now(),
                    'type' => $success_type, //还款成功后根据还款计划表三方数据更新状态
                    'repay_date' => $repay_date, //实际还款日期
                ]);
            }
            DB::commit();
            //催收更新分案后的案件
            event(new RepayMentEvent($model->summary_id));
            //资方成功推到月保 RepayMonthJobQueue
            RepayMonthJobQueue::dispatch($model->record_id);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::debug('repay_get_money_exception', [
                'summary_id' => $model->summary_id,
                'repay_plan_data' => $repay_plan_data,
                'message' => $e->getMessage(),
                'line' => $e->getLine()
            ]);
            throw new GeneralException($e->getMessage());
        }
        return true;
    }

    /**
     * Description: 资金失败处理
     * Author: Gxs
     * @param RepayRecordMoney $model
     * @param $data
     * @return bool
     * @throws GeneralException
     */
    private function _failure($model, $data)
    {
        try {
            //如果是代扣Api调用对应事件
            if($model->record->apply_number){
                event(new CollectionReceiptEvent($model->record_id));
            }

            DB::beginTransaction();
            //资金记录表更新失败状态
            $model->where('id', $model->id)->update([
                'status' => $model::STATUS_THREE,
                'failure' => $data['resultRemark'],
                'status_time' => Carbon::now()
            ]);
            //记录总表更新失败理由
            $record = [
                'status' => RepayRecord::STATUS_THREE,
                'failure_status' => RepayRecord::FAILURE_STATUS_ONE,
                'failure_message' => $data['resultRemark'],
            ];
            $model->record()->where('id', $model->record_id)->update($record);
            //用户全局状态变更
            UserGlobal::where('uid', $model->uid)->update(['global_status' => UserGlobal::STATUS_REPAY_FAILURE]);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            throw new GeneralException($e->getMessage());
        }
        return true;
    }

    /**
     * 要处理的失败任务。
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception){}
}